package com.tianji.learning.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.api.dto.leanring.PointsRecordMsgDTO;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.DateUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.entity.PointsRecord;
import com.tianji.learning.mapper.PointsRecordMapper;
import com.tianji.learning.pojo.PointsRecordType;
import com.tianji.learning.service.IPointsRecordService;
import com.tianji.learning.vo.PointsStatisticsVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static com.tianji.common.constants.RedisConstants.BOARD_KEY;

/**
 * <p>
 * 学习积分记录，每个月底清零 服务实现类
 * </p>
 *
 * @author xjs
 */
@Service
public class PointsRecordServiceImpl extends ServiceImpl<PointsRecordMapper, PointsRecord> implements IPointsRecordService {


    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public List<PointsStatisticsVO> today() {
        //  获取当前用户
        Long userId = UserContext.getUser();
        //   今天的开始和结束
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime dayStartTime = DateUtils.getDayStartTime(now);
        LocalDateTime dayEndTime = DateUtils.getDayEndTime(now);
        List<PointsRecord> records = this.baseMapper.todayStatistics(userId,dayStartTime,dayEndTime);
        if(CollectionUtils.isEmpty(records)){
            return new ArrayList<>();
        }
        List<PointsStatisticsVO> voList = new ArrayList<>();
        for (PointsRecord record : records) {
            PointsStatisticsVO vo = new PointsStatisticsVO();
            PointsRecordType recordType = PointsRecordType.of(record.getType());
            vo.setType(recordType.getDesc());
            vo.setMaxPoints(recordType.getMaxPoints());
            vo.setPoints(record.getPoints());
            voList.add(vo);
        }
        return voList;
    }

    @Override
    public void onPointsRecordChange(PointsRecordMsgDTO msg) {
        // 判断是否有积分的上限
        Integer type = msg.getType();
        PointsRecordType recordType = PointsRecordType.of(type);
        int maxPoints = recordType.getMaxPoints();
        if(maxPoints <= 0){
            // 没有上限
            // 直接保存积分记录
            PointsRecord record = BeanUtils.copyBean(msg, PointsRecord.class);
            this.save(record);
            // 修改用户积分的排行榜
            addUserPointBoard(msg.getUserId(), msg.getPoints().doubleValue());
            return;
        }
        // 有
        //   查询今天当前用户已经获取了多少积分
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime dayStartTime = DateUtils.getDayStartTime(now);
        LocalDateTime dayEndTime = DateUtils.getDayEndTime(now);
        int oldPoints =this.baseMapper.sumTodayPointsByUserAndType(msg.getUserId(), msg.getType(), dayStartTime, dayEndTime);
        //   判断积分是否超过上限
        if(oldPoints >= maxPoints){
            //   超了，丢弃消息，结束
            return;
        }
        // 没超，保存积分记录
        PointsRecord record = BeanUtils.copyBean(msg, PointsRecord.class);
        int realPoint = msg.getPoints();
        // 如果说已有的积分+当前的积分超过了最大积分
        if(oldPoints + msg.getPoints() > maxPoints){
            // 现在能保存的积分=最大积分 - 已有的积分
            realPoint = maxPoints - oldPoints;
        }
        record.setPoints(realPoint);
        this.save(record);
        // 修改用户积分的排行榜
        addUserPointBoard(msg.getUserId(), realPoint);
    }

    private void addUserPointBoard(Long userId, double point){
        String key = getBoardKey(LocalDateTime.now());
        redisTemplate.opsForZSet().incrementScore(key, ""+userId, point);
    }

    @Override
    public String getBoardKey(LocalDateTime now) {
        String yyyyMM = DateUtils.format(now, "yyyyMM");
        return BOARD_KEY + yyyyMM;
    }
}
